'use strict';
import * as sequelize from 'sequelize';
import BaseService from './base';
import { ICommentAttr } from '../model/comment';
// import { transformTozTreeFormat } from '../utils';
const createRule = {
  articleId: {
    type: 'number',
    required: true,
  },
  fromUserId: {
    type: 'number',
    required: true,
  },
  toUserId: {
    type: 'number',
    required: true,
  },
  replyId: {
    type: 'number',
    required: false,
  },
  content: {
    type: 'string',
    required: true,
  },
  main: {
    type: 'boolean',
    required: false,
  },
};

interface ICommentQueryParams {
  page?: number;
  limit?: number;
  articleId?: number;
}

export default class extends BaseService {
  async list({ articleId }: ICommentQueryParams) {
    const { ctx } = this;
    const userId = ctx.userId;
    let { list, pagination } = await this.pagination(ctx.model.Comment, {
      where: { articleId},
      order: [
        ['createdAt', 'DESC'],
      ],
      include: [{
        model: ctx.model.User,
        as: 'from',
        attributes: { exclude: ['password'] },
      }, {
        model: ctx.model.User,
        as: 'to',
        attributes: { exclude: ['password'] },
      }],
      distinct: true,     // 解决关联查询返回的数据总数异常问题
    });
    const commentIds: number[] = list.map(item => item.id);
    let userLikeComments = await ctx.model.CommentLike.findAll({
      where: {
        userId,
      },
      attributes: [
        'userId',
        'commentId',
      ],
    });
    let likes = await ctx.model.CommentLike.findAll({
      where: {
        commentId: {
          [sequelize.Op.in]: commentIds,
        },
      },
      attributes: [
        'commentId',
        [sequelize.fn('COUNT', sequelize.col('*')), 'likeCount'],
      ],
      group: 'commentId',
    });
    likes = JSON.parse(JSON.stringify(likes));
    userLikeComments = JSON.parse(JSON.stringify(userLikeComments));
    list = list.map(item => {
      item = item.toJSON();
      item.likeCount = 0;
      item.isLike = false;
      item.replys = [];
      for (let i = 0; i < likes.length; i++) {
        if (likes[i].commentId === item.id) {
          item.likeCount = likes[i].likeCount || 0;
          break;
        }
      }
      for (let i = 0; i < userLikeComments.length; i++) {
        if (userLikeComments[i].commentId === item.id) {
          item.isLike = true;
          break;
        }
      }
      return item;
    });
    return {
      list, pagination,
    };
  }
  /**
   * @description: 新增评论
   * @param {number} articleId 文章ID       [required]
   * @param {number} fromUserId 来自谁的评论 [required]
   * @param {number} toUserId 回复谁        [required]
   * @param {string} content 回复内容       [required]
   * @param {number} replyId 评论ID（回复）
   * @param {bollean} main 是否发表到主评论
   * @return:
  */
  async doSave({ articleId, fromUserId, toUserId, content, replyId, main = false }: ICommentAttr) {
    const { ctx, service } = this;
    const payload = {
      articleId,
      fromUserId,
      toUserId,
      replyId,
      content,
      main,
    };
    ctx.validate(createRule, payload);
    const article = await service.article.findByPk(articleId);
    if (!article) {
      ctx.fail('该文章不存在或已被删除', 404001)
      // ctx.throwBizError({ message: '该文章不存在或已被删除', log: false });
      return;
    }
    if (!article.allowComment) {     // 没有开启评论
      ctx.fail('暂时无法对改文章进行评论', 403001)
      // ctx.throwBizError({ message: '暂时无法对改文章进行评论', log: false });
      return;
    }
    return await ctx.model.Comment.create(payload);
  }
  /**
   * @description: 评论点赞
   * @param {number} commentId 评论ID
   * @param {number} userId 用户ID
   * @return:
  */
  async toggleLike(commentId: number, userId: number) {
    const { ctx } = this;
    const comment = await ctx.model.Comment.findByPk(commentId);
    if (!comment) {
      ctx.fail('评论不存在', 404001)
      // ctx.throwBizError({ message: '评论不存在', log: false });
      return;
    }
    let isLike: boolean;
    let condition: object;
    const query = {
      commentId,
      userId,
    };
    const commentLike = await ctx.model.CommentLike.scope('all').findOne({
      where: query,
    });
    if (commentLike) {
      if (commentLike.status === 1) {
        condition = { status: 0 };
        isLike = false;
      } else {
        condition = { status: 1 };
        isLike = true;
      }
      await ctx.model.CommentLike.scope('all').update(condition, {
        where: query,
      });
    } else {
      await ctx.model.CommentLike.create({
        status: 1,
        userId,
        commentId,
      });
      isLike = true;
    }
    const count = await ctx.model.CommentLike.count({
      where: {
        commentId,
      },
    });
    return {
      userId,
      isLike,
      count,
    };
  }
  /**
   * @description: 获取评论点赞用户
   * @param {number} id 评论ID
   * @return:
  */
  async getLikeUsersById(id: number) {
    const { ctx } = this;
    return await ctx.model.Comment.findByPk(id, {
      include: [
        {
          model: ctx.model.User,
          as: 'likeUsers',
          attributes: { exclude: ['password'] },
          through: {
            attributes: [],
            where: {
              status: 1,
            },
          },
        },
      ],
    });
  }
}
